# -*- coding:utf-8 -*-
"""
@Time : 2025/03/22 11:17 AM
@Author: linfeng
@Des: 基础模型
"""

from enum import IntEnum
import enum
from pydantic import ConfigDict, field_validator
from tortoise import fields, models
from tortoise.models import Model
from tortoise.contrib.pydantic import pydantic_model_creator, pydantic_queryset_creator

class TimestampMixin(Model):
    create_time = fields.DatetimeField(auto_now_add=True, description='创建时间')
    update_time = fields.DatetimeField(auto_now=True, description="更新时间")

    class Meta:
        abstract = True


class Admin(TimestampMixin):
    role: fields.ManyToManyRelation["Role"] = \
        fields.ManyToManyField("base.Role", related_name="admin", on_delete=fields.CASCADE, through="xm_admin_role")
    adminname = fields.CharField(null=True, max_length=20, description="用户名")
    admin_type = fields.BooleanField(default=False, description="用户类型 True:超级管理员 False:普通管理员")
    password = fields.CharField(null=True, max_length=255)
    nickname = fields.CharField(default='xiaomi', max_length=255, description='昵称')
    admin_phone = fields.CharField(null=True, description="手机号", max_length=11)
    admin_email = fields.CharField(null=True, description='邮箱', max_length=255)
    full_name = fields.CharField(null=True, description='姓名', max_length=255)
    admin_status = fields.IntField(default=0, description='0未激活 1正常 2禁用')
    header_img = fields.CharField(null=True, max_length=255, description='头像')
    sex = fields.IntField(default=0, null=True, description='0未知 1男 2女')
    remarks = fields.CharField(null=True, max_length=30, description="备注")
    client_host = fields.CharField(null=True, max_length=19, description="访问IP")

    class Meta:
        table_description = "用户表"
        table = "xm_admin"


class Role(TimestampMixin):
    admin: fields.ManyToManyRelation[Admin]
    role_name = fields.CharField(max_length=15, description="角色名称")
    access: fields.ManyToManyRelation["Access"] = \
        fields.ManyToManyField("base.Access", related_name="role", on_delete=fields.CASCADE, through="xm_role_access")
    role_status = fields.BooleanField(default=False, description="True:启用 False:禁用")
    role_desc = fields.CharField(null=True, max_length=255, description='角色描述')

    class Meta:
        table_description = "角色表"
        table = "xm_role"


class Access(TimestampMixin):
    role: fields.ManyToManyRelation[Role]
    access_name = fields.CharField(max_length=15, description="权限名称")
    parent_id = fields.IntField(default=0, description='父id')
    scopes = fields.CharField(unique=True, max_length=255, description='权限范围标识')
    access_desc = fields.CharField(null=True, max_length=255, description='权限描述')
    menu_icon = fields.CharField(null=True, max_length=255, description='菜单图标')
    is_check = fields.BooleanField(default=False, description='是否验证权限 True为验证 False不验证')
    is_menu = fields.BooleanField(default=False, description='是否为菜单 True菜单 False不是菜单')

    class Meta:
        table_description = "权限表"
        table = "xm_access"


class AccessLog(TimestampMixin):
    admin_id = fields.IntField(description="用户ID")
    target_url = fields.CharField(null=True, description="访问的url", max_length=255)
    user_agent = fields.TextField(null=True, description="访问UA")
    request_params = fields.JSONField(null=True, description="请求参数get|post")
    ip = fields.CharField(null=True, max_length=32, description="访问IP")
    note = fields.CharField(null=True, max_length=255, description="备注")

    class Meta:
        table_description = "用户操作记录表"
        table = "xm_access_log"

class ConfigGroup(Model):
    id = fields.IntField(primary_key=True)
    group_title = fields.CharField(max_length=50, default='')
    sort = fields.IntField(default=0)
    group_key = fields.CharField(max_length=50, default='')
    status = fields.IntField(default=0)
    types = fields.IntField(default=0)

    class Meta:
        table = "xm_config_group"

class Config(Model):
    id = fields.IntField(primary_key=True)
    group: fields.ForeignKeyRelation[ConfigGroup] = fields.ForeignKeyField(
        "base.ConfigGroup", related_name="configs", null=True, on_delete=fields.CASCADE)
    config_key = fields.CharField(max_length=50, default='')
    config_title = fields.CharField(max_length=50, default='')
    config_value = fields.TextField()
    sort = fields.IntField(default=0)
    config_type = fields.IntField(default=0)
    data_value = fields.TextField()
    data_text = fields.CharField(max_length=255, null=True)
    right_type = fields.IntField(default=0)
    upload_type = fields.IntField(default=0)
    status = fields.IntField(default=0)
    is_sys = fields.IntField(default=0)
    is_hide = fields.SmallIntField(default=0)

    class Meta:
        table = "xm_config"
        indexes = ("config_key", "group_id")

class CateType(IntEnum):
    LINK = -2       # 链接
    SINGLE_PAGE = -1 # 单页
    ARTICLE = 1      # 文章
    PRODUCT = 2      # 产品
    JOB = 3          # 招聘

class Category(Model):
    cate_id = fields.IntField(pk=True)
    cate_name = fields.CharField(max_length=30, description="栏目名称")
    cate_en_name = fields.CharField(max_length=30, description="英文名称")
    cate_type = fields.IntEnumField(
        CateType,
        default=CateType.ARTICLE,
        description="类型：LINK(-2), SINGLE_PAGE(-1), ARTICLE(1), PRODUCT(2), JOB(3)"
    )
    cate_url = fields.CharField(max_length=255, null=True, description="链接地址")
    cate_list = fields.CharField(max_length=255, null=True, description="列表模板")
    cate_show = fields.CharField(max_length=255, null=True, description="详情模板")
    cate_title = fields.CharField(max_length=255, null=True, description="标题")
    cate_key = fields.CharField(max_length=255, null=True, description="关键字")
    cate_desc = fields.CharField(max_length=255, null=True, description="描述")
    is_blank = fields.BooleanField(default=False, description="新窗口")
    sort = fields.IntField(default=0, description="排序")
    status = fields.BooleanField(default=False, description="状态")
    parent_id = fields.IntField(default=0, description="父级ID")


    def __str__(self):
        return self.cate_name

    class Meta:
        table = "xm_category"
        table_description = "栏目表"
        indexes = ("parent_id",)  # 创建索引
        ordering = ["sort"]        # 默认排序

CategoryPydantic = pydantic_model_creator(
    Category, 
    name="Category",
    exclude=("children",)  # 排除递归关系
)
CategoryInPydantic = pydantic_model_creator(
    Category, 
    name="CategoryIn",
    exclude_readonly=True,
    include=("cate_name", "cate_type", "cate_url", "sort", "status", "parent_id")
)

class Content(TimestampMixin):
    id = fields.IntField(primary_key=True)
    title = fields.CharField(max_length=255, verbose_name="标题", null=True)
    category: fields.ForeignKeyNullableRelation["Category"] = fields.ForeignKeyField(
        "base.Category", related_name="contents", null=True)
    pic = fields.CharField(max_length=255, verbose_name="图片", null=True)
    ispic = fields.BooleanField(default=False, verbose_name="是否图片")
    hots = fields.IntField(default=0, verbose_name="热度")
    sort = fields.IntField(default=0, verbose_name="排序")
    isnice = fields.BooleanField(default=False, verbose_name="推荐") 
    istop = fields.BooleanField(default=False, verbose_name="置顶")
    islock = fields.BooleanField(default=False, verbose_name="状态")

    def __str__(self):
        return self.title
    
    class Meta:
        table = "xm_content"
        table_description = "内容表"


class ModelPage(models.Model):
    pageid = fields.IntField(primary_key=True)
    cate: fields.OneToOneRelation["Category"] = fields.OneToOneField(
        "base.Category", on_delete=fields.OnDelete.CASCADE, related_name="model_page")
    piclist = fields.TextField(verbose_name="图片列表")
    content = fields.TextField(verbose_name="正文")

    class Meta:
        table = "xm_model_page"
        table_description = "单页模型表"

# 单页内容输入模型
ModelPagePydanticIn = pydantic_model_creator(
    ModelPage,
    name="ModelPageIn",
    exclude=["pageid"]  # 创建时无需提供 pageid
)

class ModelNews(models.Model):
    newsid = fields.IntField(primary_key=True)
    con: fields.OneToOneRelation["Content"] = fields.OneToOneField(
        "base.Content", on_delete=fields.OnDelete.CASCADE, related_name="model_news")
    content = fields.TextField(verbose_name="正文")

    class Meta:
        table = "xm_model_news"
        table_description = "新闻模型表"


class ModelPro(models.Model):
    proid = fields.IntField(primary_key=True)
    con: fields.OneToOneRelation["Content"] = fields.OneToOneField(
        "base.Content", on_delete=fields.OnDelete.CASCADE, related_name="model_pro")
    content = fields.TextField(verbose_name="正文")
    price = fields.DecimalField(max_digits=10, decimal_places=2, verbose_name="价格", default=0.00)
    piclist = fields.TextField(verbose_name="图片列表")

    class Meta:
        table = "xm_model_pro"
        table_description = "产品模型表"

class ModelJob(models.Model):
    jobid = fields.IntField(primary_key=True)
    con: fields.OneToOneRelation["Content"] = fields.OneToOneField(
        "base.Content", on_delete=fields.OnDelete.CASCADE, related_name="model_job")
    content = fields.TextField(verbose_name="工作内容")

    class Meta:
        table = "xm_model_job"
        table_description = "招聘模型表"

class PictureGroup(models.Model):
    group_name = fields.CharField(max_length=255, verbose_name="分类名称")
    status = fields.BooleanField(default=True, verbose_name="状态")
    sort = fields.IntField(default=0, verbose_name="排序")

    def __str__(self):
        return self.group_name
    class Meta:
        table = "xm_picture_group"
        table_description = "图片分组表"

class Tags(models.Model):
    title = fields.CharField(max_length=255, verbose_name="标签名称")
    hits = fields.IntField(default=0, verbose_name="热度")
    status = fields.BooleanField(default=True, verbose_name="状态")

    class Meta:
        table = "xm_tags"
        table_description = "标签表"

class Picture(models.Model):
    title = fields.CharField(max_length=255, verbose_name="标题")
    pic = fields.CharField(max_length=255, verbose_name="路径")
    group: fields.ForeignKeyRelation[PictureGroup] = fields.ForeignKeyField(
        "base.PictureGroup", related_name="pictures", null=True, on_delete=fields.CASCADE)
    tags: fields.ManyToManyRelation["Tags"] = fields.ManyToManyField("base.Tags", related_name="pictures", on_delete=fields.CASCADE, through="xm_picture_tags")
    hits = fields.IntField(default=0, verbose_name="热度")
    sort = fields.IntField(default=0, verbose_name="排序")
    author = fields.CharField(max_length=255, verbose_name="作者", null=True)
    description = fields.TextField(verbose_name="描述", null=True)
    is_nice = fields.BooleanField(verbose_name="是否推荐", default=False)
    is_top = fields.BooleanField(verbose_name="是否置顶", default=False)
    status = fields.BooleanField(default=True, verbose_name="状态")
    create_time = fields.DatetimeField(auto_now_add=True, description='创建时间')
    update_time = fields.DatetimeField(auto_now=True, description="更新时间")
    
    class Meta:
        table = "xm_picture"
        table_description = "图片表"


class Ad(models.Model):
    title = fields.CharField(max_length=255, verbose_name="广告名称")
    sort = fields.IntField(verbose_name="排序", default=0)
    status = fields.BooleanField(verbose_name="状态", default=True)
    is_sys = fields.BooleanField(verbose_name="系统自带", default=False)
    a_key = fields.CharField(max_length=20, verbose_name="关键字", null=True)

    class Meta:
        table = "xm_ad"
        table_description = "广告"

class AdPicture(models.Model):
    title = fields.CharField(max_length=255, verbose_name="标题")
    pic = fields.CharField(max_length=255, verbose_name="图片")
    ad: fields.ForeignKeyRelation[Ad] = fields.ForeignKeyField(
        "base.Ad", related_name="ad_pictures", null=True, on_delete=fields.CASCADE)
    link = fields.CharField(max_length=255, verbose_name="跳转链接", null=True)
    sort = fields.IntField(default=0, verbose_name="排序")
    status = fields.BooleanField(default=True, verbose_name="状态")
    
    class Meta:
        table = "xm_ad_picture"
        table_description = "广告图片"